Skip to content

feat(agents): Option B — _BackendProtocol in langchain, backend on AgentRuntime#37928

Open
Sydney Runkle (sydney-runkle) wants to merge 1 commit into
sr/agent-runtimefrom
sr/agent-runtime-option-b
Open

feat(agents): Option B — _BackendProtocol in langchain, backend on AgentRuntime#37928
Sydney Runkle (sydney-runkle) wants to merge 1 commit into
sr/agent-runtimefrom
sr/agent-runtime-option-b

Conversation

@sydney-runkle

Copy link
Copy Markdown
Collaborator

Alternative to the approach in this branch — moves the backend protocol definition into langchain so `AgentRuntime.backend` is properly typed at the langchain layer.

```python
class _BackendProtocol(Protocol): # private to langchain
def read(self, path: str) -> str: ...
def write(self, path: str, content: str) -> Any: ...
def ls(self, path: str) -> Any: ...
def download_files(self, paths: list[str]) -> Any: ...
async def aread(self, path: str) -> str: ...
async def awrite(self, path: str, content: str) -> Any: ...
async def als(self, path: str) -> Any: ...
async def adownload_files(self, paths: list[str]) -> Any: ...

DataClass
class AgentRuntime(Runtime[ContextT]):
...
backend: _BackendProtocol | None = None # properly typed

def create_agent(model, tools=None, *, backend: _BackendProtocol | None = None, ...): ...
```

vs. Option A (current branch)

Option A Option B
backend typing in langchain object | None (loose) _BackendProtocol | None (typed)
deepagents subclass AgentRuntime(LCAgentRuntime) none
BackendMiddleware public, required not needed
BackendProtocol owner deepagents langchain (private)
runtime.backend in DA hooks non-optional, typed optional (None-guard needed)

…entRuntime

- _BackendProtocol: private Protocol with core backend methods (read/write/ls etc.)
- AgentRuntime.backend: _BackendProtocol | None — typed at the langchain layer
- create_agent accepts backend= and threads it into AgentRuntime at dispatch time
- No AgentRuntime subclass or BackendMiddleware needed in subpackages
@github-actions github-actions Bot added feature For PRs that implement a new feature; NOT A FEATURE REQUEST internal langchain `langchain` package issues & PRs size: XS < 50 LOC labels Jun 5, 2026

@open-swe open-swe Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Open SWE Review found 1 potential issue.

View Open SWE trace

model_settings: dict[str, Any] = field(default_factory=dict)
"""Additional model-specific settings."""

backend: _BackendProtocol | None = field(default=None)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Backend cannot be overridden on ModelRequest

Adding AgentRuntime.backend makes backend part of the runtime state carried by model middleware, but ModelRequest.override() still only treats model/system_prompt/tool_choice/tools/response_format/model_settings as runtime fields. A middleware that tries to replace or clear the backend for a nested handler call via request.override(backend=...) will route backend to dataclasses.replace(self, ...) on ModelRequest, which raises TypeError: ModelRequest.__init__() got an unexpected keyword argument 'backend' at runtime. Include backend in the override typed dict and _runtime_fields (and optionally expose a backend property) so backend behaves like the other AgentRuntime fields.

(Refers to line 120)


Was this helpful? React with 👍 or 👎 to provide feedback.

@mdrxy Mason Daugherty (mdrxy) changed the title feat(agents): Option B — _BackendProtocol in langchain, backend on AgentRuntime feat(agents): Option B — _BackendProtocol in langchain, backend on AgentRuntime Jun 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature For PRs that implement a new feature; NOT A FEATURE REQUEST internal langchain `langchain` package issues & PRs size: XS < 50 LOC

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant